package com.samsung.sbackup;

import java.io.File;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import net.lingala.zip4j.exception.ZipException;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Telephony.Sms;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.samsung.adapter.AppsAdapter;
import com.samsung.adapter.FileAdapter2;
import com.samsung.adapter.RestoreItemsAdapter;
import com.samsung.handler.CalendarHandler;
import com.samsung.handler.ContactHandler;
import com.samsung.handler.SmsHandler;
import com.samsung.handler.ZipHandler;
import com.samsung.item.FileItem;
import com.samsung.item.RestoreItem;

public class QuickRestore extends Activity {

	Button btnBack, btnRestore;
	ListView lvRestore;
	RestoreItemsAdapter adapter;
	ArrayList<RestoreItem> restoreItems;
	EditText etPassword;
	String Path;
	SmsHandler sms;
	CalendarHandler calendar;
	Context ctx;
	ContactHandler contact;
	Dialog dialog;
	ProgressDialog dialogpro = null;
	SharedPreferences sharedPref;

	@TargetApi(19)
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.quick_restore);
		ctx = this;
		getActionBar().setDisplayHomeAsUpEnabled(true);

		sharedPref = PreferenceManager
				.getDefaultSharedPreferences(getApplicationContext());

		btnBack = (Button) findViewById(R.id.quick_restore_btnBack);
		btnRestore = (Button) findViewById(R.id.quick_restore_btnRestore);
		lvRestore = (ListView) findViewById(R.id.quick_restore_listView);
		restoreItems = new ArrayList<RestoreItem>();
		adapter = new RestoreItemsAdapter(this, R.layout.restore_items,
				restoreItems);
		adapter.addItem(new RestoreItem("Contacts", R.drawable.contacts));
		adapter.addItem(new RestoreItem("Sms", R.drawable.sms));
		adapter.addItem(new RestoreItem("Calendar", R.drawable.calendar));
		adapter.addItem(new RestoreItem("Apps", R.drawable.apps));
		lvRestore.setAdapter(adapter);

		lvRestore.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				for (RestoreItem item : adapter.getAllItems()) {
					item.setChecked(false);
				}
				adapter.getItem(position).setChecked(true);
				adapter.notifyDataSetChanged();
			}
		});

		btnBack.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				onBackPressed();
			}
		});

		btnRestore.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				if (restoreItems.get(0).isChecked()) {
					System.out.println("0");
					createDialog_2("contact");

				}
				if (restoreItems.get(1).isChecked()) {
					if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.KITKAT) {
						Intent intent = new Intent(
								Sms.Intents.ACTION_CHANGE_DEFAULT);
						intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME,
								getPackageName());
						startActivity(intent);
					}
					createDialog_2("sms");
				}
				if (restoreItems.get(2).isChecked()) {
					createDialog_2("calendar");
				}
				if (restoreItems.get(3).isChecked()) {
					new LoadAppsTask().execute();
				}
			}
		});
	}

	class LoadAppsTask extends AsyncTask<Void, Void, String> {

		ProgressDialog progressDialog;
		ListView lv;
		AppsAdapter appsAdapter;
		String folder;
		String returnString;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			dialog = new Dialog(QuickRestore.this);
			dialog.setContentView(R.layout.custom_dialog_2);
			dialog.setTitle("Choose apps to restore");

			lv = (ListView) dialog.findViewById(R.id.list_2);
			progressDialog = new ProgressDialog(QuickRestore.this);
			progressDialog.setMessage("Loading applications...");
			progressDialog.setCancelable(false);
			progressDialog.show();
			returnString = "";
		}

		@Override
		protected String doInBackground(Void... params) {

			folder = sharedPref.getString(
					FragmentSettingsPreference.BACKUP_PATH, "/") + "/" + "app";
			ArrayList<ApplicationInfo> backedUpApps = new ArrayList<ApplicationInfo>();
			SparseArray<Drawable> hashMapIcon = new SparseArray<Drawable>();
			SparseArray<String> hashMapName = new SparseArray<String>();
			File filesApk = new File(folder);
			if (!filesApk.exists())
				filesApk.mkdirs();
			File[] apks = filesApk.listFiles();
			if (apks != null && apks.length != 0) {
				for (int i = 0; i < apks.length; i++) {
					if (apks[i].getPath().endsWith(".apk")) {
						PackageInfo packageInfo = QuickRestore.this
								.getPackageManager().getPackageArchiveInfo(
										apks[i].getPath(),
										PackageManager.GET_ACTIVITIES);
						if (packageInfo != null) {
							ApplicationInfo appInfo = packageInfo.applicationInfo;
							if (Build.VERSION.SDK_INT >= 8) {
								appInfo.sourceDir = apks[i].getPath();
								appInfo.publicSourceDir = apks[i].getPath();
							}
							backedUpApps.add(appInfo);
							hashMapName.put(i,
									appInfo.loadLabel(getPackageManager())
											.toString());
							hashMapIcon.put(i,
									appInfo.loadIcon(getPackageManager()));
						}
					}
				}
			}

			if (apks == null)
				System.out.println("Apps backup folder is invalid");
			else if (apks.length == 0)
				returnString = "None";
			else
				returnString = String.valueOf(apks.length) + " apps found";

			boolean[] checkedItems = new boolean[apks.length];
			for (int i = 0; i < checkedItems.length; i++) {
				checkedItems[i] = true;
			}

			appsAdapter = new AppsAdapter(QuickRestore.this, backedUpApps,
					R.layout.app_item, hashMapIcon, hashMapName, checkedItems);
			return returnString;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			progressDialog.dismiss();
			lv.setAdapter(appsAdapter);
			lv.setOnItemClickListener(new OnItemClickListener() {

				@Override
				public void onItemClick(AdapterView<?> arg0, View arg1,
						int arg2, long arg3) {
					appsAdapter.getCheckedItems()[arg2] = !appsAdapter
							.getCheckedItems()[arg2];
					appsAdapter.notifyDataSetChanged();
				}
			});
			if (result.equals("None")) {
				Toast.makeText(QuickRestore.this, "No backups found",
						Toast.LENGTH_LONG).show();
				lv.setVisibility(View.GONE);
			} else
				Toast.makeText(QuickRestore.this, result, Toast.LENGTH_SHORT)
						.show();

			Button btnOk = (Button) dialog.findViewById(R.id.dialog_bt_ok_2);
			Button btnCancel = (Button) dialog
					.findViewById(R.id.dialog_bt_cancel_2);
			btnCancel.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					dialog.dismiss();
				}
			});

			btnOk.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					dialog.dismiss();
					ArrayList<ApplicationInfo> selectedItems = appsAdapter
							.getSelectedItems();
					for (ApplicationInfo app : selectedItems) {
						Intent intent = new Intent(Intent.ACTION_VIEW);
						intent.setDataAndType(
								Uri.fromFile(new File(folder + "/"
										+ app.loadLabel(getPackageManager())
										+ ".apk")),
								"application/vnd.android.package-archive");
						intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
						startActivity(intent);
					}
				}
			});

			dialog.show();
		}
	}

	public void createDialog_2(final String fileName) {
		dialog = new Dialog(QuickRestore.this);
		dialog.setContentView(R.layout.custom_dialog_2);
		dialog.setTitle("Choose one file to restore");

		final String folder = sharedPref.getString(
				FragmentSettingsPreference.BACKUP_PATH, "/");

		final ListView lv = (ListView) dialog.findViewById(R.id.list_2);
		final FileAdapter2 adapter = new FileAdapter2(getApplicationContext());
		lv.setAdapter(adapter);
		File[] files = new File(folder).listFiles();

		if (files != null) {
			for (File s : files) {
				if (s.getName().contains(".xml")
						|| s.getName().contains(".vcf"))
					s.delete();
				adapter.notifyDataSetChanged();
			}

			for (File s : files) {
				boolean fileHasPass = false;
				try {
					if (s.isFile()) {
						fileHasPass = ZipHandler.isPassword(folder + "/"
								+ s.getName());
					}
				} catch (ZipException e) {
					e.printStackTrace();
				}
				if (fileName.equals("calendar_") || fileName.equals("calendar")) {
					if (s.getName().contains("calendar")
							&& !(s.getName().contains(".xml") || s.getName()
									.contains(".vcf")))
						adapter.addItem(new FileItem(s.getName(), false,
								fileHasPass));
				}
				if (fileName.equals("contact_") || fileName.equals("contact")) {
					if (s.getName().contains("contact")
							&& !(s.getName().contains(".xml") || s.getName()
									.contains(".vcf")))
						adapter.addItem(new FileItem(s.getName(), false,
								fileHasPass));
				}
				if (fileName.equals("sms_") || fileName.equals("sms")) {
					if (s.getName().contains("sms")
							&& !(s.getName().contains(".xml") || s.getName()
									.contains(".vcf")))
						adapter.addItem(new FileItem(s.getName(), false,
								fileHasPass));
				}
			}
		} else {
			lv.setVisibility(View.GONE);
			Toast.makeText(QuickRestore.this, "No backups found",
					Toast.LENGTH_LONG).show();
		}
		lv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				adapter.getItem(arg2).setChecked(
						!adapter.getItem(arg2).isChecked());
				for (int i = 0; i < adapter.getCount(); i++) {
					if (i != arg2) {
						adapter.getItem(i).setChecked(false);
					}
				}
				adapter.notifyDataSetChanged();
				Path = folder + "/" + adapter.getItem(arg2).getFileName();
				Log.e("path", Path.substring(0, Path.lastIndexOf("/")));
			}
		});

		Button btOk = (Button) dialog.findViewById(R.id.dialog_bt_ok_2);
		Button btCancel = (Button) dialog.findViewById(R.id.dialog_bt_cancel_2);
		btOk.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				boolean c = false;
				for (int i = 0; i < adapter.getCount(); i++) {
					if (adapter.getItem(i).isChecked())
						c = true;
				}

				if (c == true) {
					dialog.dismiss();
					if (fileName.equals("calendar")) {
						createDialogPassword("calendar");
					} else if (fileName.equals("sms")) {
						createDialogPassword("sms");
					} else if (fileName.equals("contact")) {
						createDialogPassword("contact");
					}
				}
				dialog.dismiss();
			}
		});
		btCancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				dialog.dismiss();
			}
		});
		dialog.show();
	}

	public void createDialogPassword(final String task) {

		final Dialog dialogPw = new Dialog(QuickRestore.this);
		dialogPw.setContentView(R.layout.dialog);
		dialogPw.setTitle("Please enter password");
		etPassword = (EditText) dialogPw.findViewById(R.id.edittextPassword);
		Button btnOK = (Button) dialogPw.findViewById(R.id.btnOk);
		etPassword.setText("");
		try {
			if (ZipHandler.isPassword(Path)) {

				dialogPw.show();
				btnOK.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View arg0) {

						if (ZipHandler.verify(Path, etPassword.getText()
								.toString())
								&& !etPassword.getText().toString().isEmpty()) {
							dialogPw.dismiss();
							try {
								ZipHandler.deCompress(Path, Path.substring(0,
										Path.lastIndexOf("/")), etPassword
										.getText().toString());
							} catch (ZipException e) {
								e.printStackTrace();
							}
							if (task.equals("sms")) {
								try {
									sms = new SmsHandler(Path,
											QuickRestore.this);
								} catch (ParserConfigurationException e) {
									e.printStackTrace();
								}
								System.out.println(Path);
								dialogpro = new ProgressDialog(
										QuickRestore.this);
								dialogpro.setTitle("Restoring.....");
								dialogpro
										.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
								dialogpro.setIndeterminate(false);
								dialogpro.show();
								dialogpro.setCancelable(false);
								new RestoreSms().execute("");
								new SmsThread(Path).start();

							} else if (task.equals("calendar")) {
								dialogpro = new ProgressDialog(
										QuickRestore.this);
								dialogpro.setTitle("Restoring.....");
								dialogpro
										.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
								dialogpro.setIndeterminate(false);
								dialogpro.show();
								dialogpro.setCancelable(false);
								calendar = new CalendarHandler(Path,
										QuickRestore.this);
								new RestoreCalendar().execute("");
								new CalendarThread(Path).start();
							} else if (task.equals("contact")) {
								contact = new ContactHandler(Path,
										QuickRestore.this);
								contact.restoreContacts();
							}
						} else
							Toast.makeText(QuickRestore.this, "Wrong password",
									Toast.LENGTH_SHORT).show();
					}
				});
			} else {
				ZipHandler.deCompress(Path,
						Path.substring(0, Path.lastIndexOf("/")), "");
				if (task.equals("sms")) {
					dialogpro = new ProgressDialog(QuickRestore.this);
					dialogpro.setTitle("Restoring...");
					dialogpro.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
					dialogpro.setIndeterminate(false);
					dialogpro.show();
					dialogpro.setCancelable(false);
					try {
						sms = new SmsHandler(Path, QuickRestore.this);
					} catch (ParserConfigurationException e) {
						e.printStackTrace();
					}

					new RestoreSms().execute("");
					new SmsThread(Path).start();

				} else if (task.equals("calendar")) {
					dialogpro = new ProgressDialog(QuickRestore.this);
					dialogpro.setTitle("Restoring...");
					dialogpro.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
					dialogpro.setIndeterminate(false);
					dialogpro.show();
					dialogpro.setCancelable(false);
					calendar = new CalendarHandler(Path, QuickRestore.this);
					new RestoreCalendar().execute("");
					new CalendarThread(Path).start();
				} else if (task.equals("contact")) {
					contact = new ContactHandler(Path, QuickRestore.this);
					contact.restoreContacts();
				}
			}
		} catch (ZipException e) {
			e.printStackTrace();
		}
	}

	private class RestoreSms extends AsyncTask<String, Integer, String> {

		@Override
		protected void onPreExecute() {

			super.onPreExecute();
		}

		@Override
		protected String doInBackground(String... params) {

			dialogpro.setMax(sms.totalMessage);
			while (sms.progress < sms.totalMessage && !sms.isError()) {
				publishProgress(sms.progress);
			}
			return "Done";
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			dialogpro.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if (sms.isError())
				Toast.makeText(QuickRestore.this, sms.getErrorMessage(),
						Toast.LENGTH_LONG).show();
			else
				Toast.makeText(QuickRestore.this, result, Toast.LENGTH_SHORT)
						.show();
			dialogpro.dismiss();
		}
	}

	public class SmsThread extends Thread {

		String p;

		public SmsThread(String path) {
			p = path.replace("zip", "xml");
		}

		@Override
		public void run() {
			sms.restore(getContentResolver());
			File f = new File(p);
			f.delete();
		}
	}

	private class RestoreCalendar extends AsyncTask<String, Integer, String> {

		@Override
		protected void onPreExecute() {

			super.onPreExecute();
		}

		@Override
		protected String doInBackground(String... params) {
			dialogpro.setMax(calendar.totalRecord);
			while (calendar.progress < calendar.totalRecord
					&& !calendar.isError()) {
				publishProgress(calendar.progress);
			}
			return "Done";
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			dialogpro.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if (calendar.isError())
				Toast.makeText(QuickRestore.this, calendar.getErrorMessage(),
						Toast.LENGTH_LONG).show();
			else
				Toast.makeText(QuickRestore.this, result, Toast.LENGTH_SHORT)
						.show();
			dialogpro.dismiss();
		}
	}

	public class CalendarThread extends Thread {
		String p;

		public CalendarThread(String path) {
			p = path.replace("zip", "xml");
		}

		@Override
		public void run() {
			calendar.restoreCalendar(getContentResolver());
			File f = new File(p);
			f.delete();
		}
	}
}
